package stockin

import (
	"context"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"time"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type StockinSummaryLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewStockinSummaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StockinSummaryLogic {
	return &StockinSummaryLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *StockinSummaryLogic) StockinSummary() (resp *types.StockInSummaryResponse, err error) {
	resp = new(types.StockInSummaryResponse)

	//1.汇总数据初始化
	data := make(map[string]types.StockInSummary)
	data["today"] = types.StockInSummary{}
	data["week"] = types.StockInSummary{}
	data["month"] = types.StockInSummary{}

	now := time.Now()

	year, month, day := now.Date()
	var weekOffset int
	if now.Weekday() == time.Sunday {
		weekOffset = -6
	} else {
		weekOffset = int(time.Monday - now.Weekday())
	}

	todayStartTime := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	weekStartTime := time.Date(year, month, day, 0, 0, 0, 0, time.Local).AddDate(0, 0, weekOffset)
	monthStartTime := time.Date(year, month, 1, 0, 0, 0, 0, time.Local)

	todayEndTime := todayStartTime.Add((24*3600 - 1) * time.Second)
	weekEndTime := weekStartTime.AddDate(0, 0, 7).Add(-time.Second)
	monthEndTime := monthStartTime.AddDate(0, 1, 0).Add(-time.Second)

	fmt.Println("当前时间：", now.Format(time.DateTime))
	fmt.Println("本周第几天：", now.Weekday())
	fmt.Println("本周起始时间：", weekStartTime.Format(time.DateTime))
	fmt.Println("本周截止时间：", weekEndTime.Format(time.DateTime))
	fmt.Println("本月截止时间：", monthEndTime.Format(time.DateTime))

	//起始查询时间
	var startTime = monthStartTime
	if weekStartTime.Unix() < monthStartTime.Unix() {
		startTime = weekStartTime
	}

	//2.查询入库单概要数据
	all, err := l.svcCtx.StockInModel.FindByPage(l.ctx, fmt.Sprintf(" where date>=%d", startTime.Unix()))
	switch err {
	case model.ErrNotFound:
		resp.Code = http.StatusNoContent
		resp.Msg = "没有数据"
		return resp, nil
	case nil:
	default: //其他错误
		fmt.Printf("[Error]查询本月入库单数据:%s\n", err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//3.查询入库单详细数据
	var g errgroup.Group
	var details = make(map[int64][]model.StockInDetail, 0)
	for _, one := range all {
		item := one
		g.Go(func() error {
			list, e := l.svcCtx.StockInDetailModel.FindByPage(l.ctx, fmt.Sprintf(" where stock_id=%d", item.Id))
			switch e {
			case nil:
				details[item.Id] = append(details[item.Id], list...)
			case model.ErrNotFound:
				return nil
			default: //错误
				fmt.Printf("[Error]查询入库单[%d]详细数据:%s\n", item.Id, e.Error())
				return e
			}
			return nil
		})
	}

	err = g.Wait()
	if err != nil {
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//4.汇总数据
	for _, one := range all {
		//4.1 统计本日数据
		if one.Date >= todayStartTime.Unix() && one.Date <= todayEndTime.Unix() {
			todaySummary := data["today"]
			//4.1.1 入库单数量
			todaySummary.Orders++
			//4.1.2 入库原料总金额（元）
			todaySummary.Total += one.Total
			//4.1.3 入库原料总重量（吨）
			for _, detail := range details[one.Id] {
				todaySummary.Weight += detail.Weight
			}

			data["today"] = todaySummary
		}

		//4.2 统计本周数据
		if one.Date >= weekStartTime.Unix() && one.Date <= weekEndTime.Unix() {
			weekSummary := data["week"]
			//4.2.1 入库单数量
			weekSummary.Orders++
			//4.2.2 入库原料总金额（元）
			weekSummary.Total += one.Total
			//4.2.3 入库原料总重量（吨）
			for _, detail := range details[one.Id] {
				weekSummary.Weight += detail.Weight
			}

			data["week"] = weekSummary
		}
		//4.3 统计本月数据
		if one.Date >= monthStartTime.Unix() && one.Date <= monthEndTime.Unix() {
			monthSummary := data["month"]
			//4.3.1 入库单数量
			monthSummary.Orders++
			//4.3.2 入库原料总金额（元）
			monthSummary.Total += one.Total
			//4.3.3 入库原料总重量（吨）
			for _, detail := range details[one.Id] {
				monthSummary.Weight += detail.Weight
			}

			data["month"] = monthSummary
		}
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	resp.Data = data

	return resp, nil
}
